package com.ice.framework.common.util;

import com.ice.framework.common.exception.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * 对参数有@Null等注解进行校验
 * @author wangwei
 * @Date 2022/1/4 15:55
 */
public class BeanValidatorUtil {

    /**
     * 验证某个bean的参数，如果不通过，则异常
     *
     * @param object 被校验的参数
     */
    public static <T> void validateThrowException(T object) {
        //获得验证器
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        //执行验证
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(object);
        //如果有验证信息，则取出来包装成异常返回
        if (CollectionUtils.isEmpty(constraintViolations)) {
            return;
        }
        throw new BusinessException(convertErrorMsg(constraintViolations));
    }

    /**
     * 验证某个bean的参数, 并返回异常信息
     * @Author wangwei
     * @Date 2023/11/9
     */
    public static <T> String validate(T object) {
        //获得验证器
        Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
        //执行验证
        Set<ConstraintViolation<T>> constraintViolations = validator.validate(object);
        //如果有验证信息，则取出来包装成异常返回
        if (CollectionUtils.isEmpty(constraintViolations)) {
            return null;
        }
        return convertErrorMsg(constraintViolations);
    }

    /**
     * 转换异常信息
     * @param set
     * @param <T>
     * @return
     */
    private static <T> String convertErrorMsg(Set<ConstraintViolation<T>> set) {
        Map<String, StringBuilder> errorMap = new HashMap<>();
        String property;
        for (ConstraintViolation<T> cv : set) {
            //这里循环获取错误信息，可以自定义格式
            property = cv.getPropertyPath().toString();
            String message = cv.getMessage();
            if (errorMap.get(property) != null) {
                errorMap.get(property).append("," + message);
            } else {
                StringBuilder sb = new StringBuilder();
                sb.append(message);
                errorMap.put(property, sb);
            }
        }

        Collection<StringBuilder> stringBuilders = errorMap.values();
        return StringUtils.join(stringBuilders, "; ");
    }
}
